#include <QtOpenGL>
#include "plano.h"

Plane::Plane(int stacks, int slices) :
    Object3D(), xRange(1.0), yRange(1.0)
{
    setStacks(stacks);
    setSlices(slices);
    init();
}

void Plane::drawGeometry(void)
{

    float stepX = 2.0/slices();
    float stepY = 2.0/stacks();

    float stepCX = 1.0/slices();
    float stepCY = 1.0/stacks();

    float norm[3] = { 0.0, 0.0, 1.0 };

    program.bind();

    program.setUniformValueArray("expression", expressions, exCount);
    program.setUniformValueArray("constants", consts, consCount, 1);

    program.setUniformValue("xRange", xRange);
    program.setUniformValue("yRange", yRange);

    glNormal3fv(norm);
    float cx = 0.0;
    for(float x = -1.0; x < 1.0; x += stepX, cx += stepCX)
    {
        float cy = 0.0;
        for(float y = -1.0; y < 1.0; y += stepY, cy += stepCY)
        {
            glBegin(GL_QUADS);

            //Vert4
            glTexCoord2f(cx, cy + stepCY);
            glVertex3f(x,y + stepY,0.0);

            //Vert3
            glTexCoord2f(cx + stepCX, cy + stepCY);
            glVertex3f(x + stepX, y + stepY, 0.0);

            //Vert2
            glTexCoord2f(cx + stepCX, cy);
            glVertex3f(x + stepX, y, 0.0);

            //Vert1
            glTexCoord2f(cx, cy);
            glVertex3f(x, y, 0.0);

            glEnd();
        }
    }
    program.release();
}

void Plane::init()
{
    QGLShader *vert = new QGLShader(QGLShader::Vertex );
    QGLShader *frag = new QGLShader(QGLShader::Fragment );
    qDebug() << vert->compileSourceFile(":/autov");
    qDebug() << vert->log();
    qDebug() << frag->compileSourceFile(":/autof");
    qDebug() << frag->log();
    program.addShader(vert);
    program.addShader(frag);
    qDebug() << program.link();
    qDebug() << program.log();
}

void Plane::setXRange(GLfloat v)
{
    xRange = v;
}

void Plane::setYRange(GLfloat v)
{
    yRange = v;
}

void Plane::setExpression(const vector<Operator>& ex, const vector<float>& con)
{
    Q_ASSERT(ex.size() <= MAXARRAY && con.size() <= MAXARRAY);

    exCount = ex.size();
    for(int i = 0; i < exCount; ++i)
        expressions[i] = ex[i];

    consCount = con.size();
    for(int i = 0; i < consCount; ++i)
        consts[i] = con[i];
}
